//
//  WSSafeMutableArray.m
//  WSBaseKit
//
//  Created by zhangcong on 2020/8/13.
//  Copyright © 2020 zhangcong. All rights reserved.
//

#import "WSSafeMutableArray.h"

@implementation WSSafeMutableArray


#pragma mark - init 方法
- (instancetype)init
{
    self = [super init];
    if (self) {
        NSString* uuid = [NSString stringWithFormat:@"com.wws.array_%p", self];
        self.MSyncQueue = dispatch_queue_create([uuid UTF8String], DISPATCH_QUEUE_CONCURRENT);
        _MDataArray = [NSMutableArray array];
    }
    return self;
}


- (id)objectAtIndex:(NSUInteger)index {
    __block id obj;
    dispatch_sync(self.MSyncQueue, ^{
        if (index < [self.MDataArray count]) {
            obj = _MDataArray[index];
        }
    });
    return obj;
}


-(NSEnumerator *)objectEnumerator {
    __block NSEnumerator *enu;
    dispatch_sync(self.MSyncQueue, ^{
        enu = [self.MDataArray objectEnumerator];
    });
    return enu;
}


- (void)insertObject:(id)anObject atIndex:(NSUInteger)index{
    dispatch_barrier_async(self.MSyncQueue, ^{
        if (anObject && index < [self->_MDataArray count]) {
            [self->_MDataArray insertObject:anObject atIndex:index];
        }
    });
}


- (void)addObject:(id)anObject{
    dispatch_barrier_async(self.MSyncQueue, ^{
        if(anObject){
            [self->_MDataArray addObject:anObject];
        }
    });
}

- (void)removeObjectAtIndex:(NSUInteger)index{
    dispatch_barrier_async(self.MSyncQueue, ^{
        if (index < [self.MDataArray count]) {
            [self.MDataArray removeObjectAtIndex:index];
        }
    });
}


- (void)removeLastObject{
    dispatch_barrier_async(self.MSyncQueue, ^{
        [self.MDataArray removeLastObject];
    });
}

- (void)removeAllObjects {
    dispatch_barrier_async(self.MSyncQueue, ^{
        [self.MDataArray removeAllObjects];
    });
}

- (void)removeObjectsAtIndexes:(NSIndexSet *)indexes {
    dispatch_barrier_async(self.MSyncQueue, ^{
        if (self.MDataArray.count >= indexes.count && self.MDataArray.count > 0 && indexes.count > 0) {
            [self.MDataArray removeObjectsAtIndexes:indexes];
        }
    });
}

- (NSInteger)count {
    __block NSInteger count;
    dispatch_sync(self.MSyncQueue, ^{
        count = self.MDataArray.count;
    });
    return count;
}

- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject{
    dispatch_barrier_async(self.MSyncQueue, ^{
        if (anObject && index < [self.MDataArray count]) {
            [self.MDataArray replaceObjectAtIndex:index withObject:anObject];
        }
    });
}

- (NSUInteger)indexOfObject:(id)anObject{
    __block NSUInteger index = NSNotFound;
    dispatch_sync(self.MSyncQueue, ^{
        for (int i = 0; i < [self.MDataArray count]; i ++) {
            if ([self.MDataArray objectAtIndex:i] == anObject) {
                index = i;
                break;
            }
        }
    });
    return index;
}

- (void)enumerateObjectsWithOptions:(NSEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(id obj, NSUInteger idx, BOOL *stop))block {
    opts = NSEnumerationReverse;
    dispatch_sync(self.MSyncQueue, ^{
        [self.MDataArray enumerateObjectsWithOptions:opts usingBlock:block];
    });
}

- (void)dealloc{
    if (self.MSyncQueue) {
        self.MSyncQueue = NULL;
    }
}


@end
